﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Security.Authentication;
using System.Threading;
using System.Web;
using System.Web.Routing;
using System.Web.UI.WebControls;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OF.JsonRpc;
using OF.Microservices.DemoService.Comon;

namespace OF.Microservices.Host
{
    public class Global : System.Web.HttpApplication
    {
        protected void Application_Start(object sender, EventArgs e)
        {
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            OF.JsonRpc.JsonRpcRegister.LoadFromConfig();
            OF.JsonRpc.Config.SetErrorHandler(OnJsonRpcException);
            OF.JsonRpc.Config.SetPreProcessHandler(new PreProcessHandler(PreProcess));
            OF.JsonRpc.Config.SetCompletedProcessHandler(new CompletedProcessHandler(CompletedProcess));

            OF.JsonRpc.Client.Rpc.AddGlobalContextSetHandler((collection) =>
            {
                var contextDict = JsonRpcDataContext.GetCurrentContextDict();
                foreach (KeyValuePair<string, object> keyValuePair in contextDict)
                    collection[keyValuePair.Key] = (string) keyValuePair.Value;
            });
        }

        private OF.JsonRpc.JsonRpcException OnJsonRpcException(OF.JsonRpc.JsonRequest rpc, OF.JsonRpc.JsonRpcException ex)
        {
            // Serivce Call Service 业务异常透传
            if (ex.data is OF.JsonRpc.Client.JsonRpcException && ((OF.JsonRpc.Client.JsonRpcException)ex.data).code == 32000)
            {
                ex.code = 32000;
                ex.message = ((OF.JsonRpc.Client.JsonRpcException)ex.data).message;
                ex.data = null;
                return ex;
            }

            // Service内部产生的异常是BusinessException时，需要抛给调用端，并且指定RPC错误编码为：32000，没有堆栈。
            // 自定义代码，抛出业务异常
            if (ex.data.GetType().Name == "BusinessException")
            {
                ex.code = 32000;
                ex.message = ((Exception) ex.data).Message;
                ex.data = null;
            }
            else if (ex.data is ValidationException)
            {
                ex.code = 32000;
                ex.message = ((ValidationException) ex.data).Message;
                ex.data = null;
            }
            else
            {
                if(ex.data != null)
                    ex.data = ex.data.ToString();
            }

            return ex;
        }

        private JsonRpcException PreProcess(JsonRequest rpc, object context)
        {
            return null;
        }

        private void CompletedProcess(JsonRequest jsonRequest, JsonResponse jsonResponse, object context)
        {
            JsonRpcDataContext.RemoveContext();
        }

        protected void Session_Start(object sender, EventArgs e)
        {

        }

        protected void Application_BeginRequest(object sender, EventArgs e)
        {

        }

        protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {

        }

        protected void Application_Error(object sender, EventArgs e)
        {

        }

        protected void Session_End(object sender, EventArgs e)
        {

        }

        protected void Application_End(object sender, EventArgs e)
        {

        }
    }
}